package com.yanlight.app.controller;

import cn.jiguang.common.ClientConfig;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import com.alibaba.fastjson.JSONObject;
import com.yanlight.app.dal.entity.Certificate;
import com.yanlight.app.dal.entity.CertificateData;
import com.yanlight.app.request.WxCertRequest;
import com.yanlight.app.response.WxCertResponse;
import com.yanlight.support.wx.model.WxCertSign;
import com.yanlight.support.wx.util.SignatureUtil;
import com.yanlight.util.LogUtil;
import com.yanlight.util.RandomStringUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.List;
import java.util.SortedMap;

public class Test {

    private static final String ALGORITHM = "AES/GCM/NoPadding";
    private static final int TAG_LENGTH_BIT = 128;
    private static final int NONCE_LENGTH_BYTE = 12;
    private static final String AES_KEY = "fdca1e9bc701478ab498ee8d3ff95ab1"; // APIv3密钥
    private static final String TRANSFORMATION_PKCS1Padding = "RSA/ECB/PKCS1Padding";

    private static final String appId = "wx658022091851ab1e";
    private static final String appSecret = "dcb9034bddd1bd38b236056aeb6dc133";


    private static final String mchId = "1540792691";
    private static final String mchKey = "97215d2089b1458bb78b6f2e27ccc6f4";
    private static final String certPath = "/Users/wang/Desktop/Cert/WeChat/server/cert/apiclient_cert.p12";


    private static final String certificateKey = "certificateKey";

    private static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDKdl+aG/yXPsifI/fySe0/XUQFPPNphufsjHm5p/p08As/7iQElNJ5evI5M3R1mJOubCR4SNqFSuXvltUKAExUOUim9Xq6J/8I0uXJa1zIQnbS1BciLDClN/DMoRyRHZqDaJjqH9/w4eFd9IraU5PMvixxf+yxHqkS0tjlOPCaaUnkkHqDoxLLhrupnMJjGKynfecmViiNDNloZt30hO+r/oVHo7FCuDGLjBo3MxTERoRNhbhZziSXRHeCj2rLjyn4XG1IeVpiht7GLvy5W9ORclr5zmx9dkmq4ie7Ffh2BdN8GKqcsJ0/yxvpV/8aTxmxeSQbnrOFzG+OwQjMfCp7AgMBAAECggEAAfu64AWaKdkhmf1+Nk9nFZHSUsLQF56MsxKFNr5gg7i+Q3gPvkO+9BWyPcE1SNmfyLuid9Mu4NNlAT3XBGwQU1rkTU5mT2CI7Qsz2Q9GL2gHRfVx7JHGQDgWEcsaPomts8/Yf6KkTPXJgWQd4BmlfwH16X65UNreCSMroMM4CCsvaCpQNHJU6Z/RgkXw4cql8o8X4loxZUiZowQOnfBEklVkS0nStzoY8MuHCkJxQ/HVohGL+uwVJNBL7iyl+8eFVyu6MXd729p/3SAXahsWO9hmXCffVHezXtGD9uHnG8ax8JFaJDmceQfvt6wn8u/dAbsZkkZdVN65cD5bmowOYQKBgQDx2eS3FarjcJDSCxnSU2iTMXRfTHYPnMy2SSA0jRce8lk9AIGfJjTwpPrtB5O51VUjkqP2BgKqYyAdOLyLey48AF3m9NsbSe+uP3U5zRQHWNoVQgXoS/oI0c+H38v1JKXaaGhMj2MThKSSW2aVX6hwpcnRfMZ1Sa34tcbUsK7EWQKBgQDWTpIYdbsIS4Q28N/JFw2DDFnm+b6z3RyuCqmy+dFM5YXt42Xbdk6NGwQVWIBxG/ZUzlldp4IUkBQbGPHpgtG6pwUoisZkC7AGaHAs6bAixxiW15dGpk7cJ6w7NkIKn5vmOwyYcEreAsNZD/y6o5kgCT/zKztKgK6wrf5AggTa8wKBgQC7eX5z9dXcLHv2dih0A7gCsclVvj2eaJu/ifvvAJe1o4NNaEESj1lmWV0xtDftS9ONmbSDl7ElR2WzgTGWpcv3MwmXaKMYCj5DQmmqfrBR6axT4jQWGB8gCxPmbbL6uofeQCTphBT3IlE4KqXgkKBPghRp0WE9tfmn27DfWn5/MQKBgFfnjqGd2QQEBc2LbB/N5ur0LAREOOcKMXNqSEVzl1iVZSQ4/FTS6FGU3U3sKXM75wTOR3XU+dR5bOXYi5Ie6OxJCiKhGdN7v85BFJI3oNoDFKD6+cAvA3XmiA0Zqmk1IvuDCR2WIf+C3qIvnpjn9i1f3e1etElRE1bBZ+MJ8fflAoGBAMne7ov1KxORUm3kR5MkVLRxmaYjfU8WbBDnDdfWM6lUsn/2Hvk1I8Mlcfc4AS+hhhNSqwIsFve1w9TwTsIMMa7alQh31pxMWIVMMwgjxuSurNRNi7QWDAiReL7KzxoconoSKKTpZrTrvIaImjAAxNMYuNedbI/GeI7Ei82Lrw4q";
    private static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz6N8tq+MDSP26zwDE8USDSQguyNr5xrrwB98Z1suVtNb85EBxn+nbxgdpAReh9AOaOtrU5u6IHXw4UAnrN+7FW+5x1ZMBYqxvhr99MpUjVfgYTlJ7Mq7DBzixKTHbfzr+rOp7ubjWQccoT7RIQXfPazB7bso2InVajwUeGrMVs7FE4MTlHaUXQdc3fMY8/b0Gr5uU6qU0C4+l7Uj500Anfw4xYyrGHNd/Ji4Tw67uo/7uhJG7PCeYmsbAm8M+YJ2AOPDXUeZpkwc2FZYfz98KGPkuC4lmH2hsFO/Eqv+WXImpiVyDl+b4wVxiXuvqArmLmPpC/rFMuxeTsgWAbF7SwIDAQAB";


    private static final Logger logger = LoggerFactory.getLogger(Test.class);


    public static void main(String args[]) {

        X509Certificate x509Certificate = null;
        CertificateFactory certificateFactory = null;
        FileInputStream fileInputStream = null;

        try {
            Security.addProvider(new BouncyCastleProvider());
            certificateFactory = CertificateFactory.getInstance("X.509", "BC");
            fileInputStream = new FileInputStream("/Users/wang/Desktop/Cert/AliPay/mch/alipayRootCert.crt");
            x509Certificate = (X509Certificate) certificateFactory.generateCertificate(fileInputStream);

            String s = x509Certificate.getSerialNumber().toString();
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        LogUtil.showLog("测试", "哈哈哈");

//        try {
//            testPush();
////            for (int i = 0; i < 5; i++) {
////                testPush();
////                TimeUnit.MILLISECONDS.sleep(500);//毫秒
////            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    private static void testPush() throws Exception {
        String msg = "{\"fee\":1000,\"orderId\":5858,\"payTime\":\"2019-08-22 16:19:52\",\"payType\":2,\"sceneType\":2,\"text\":\"微信收款0.01元\"}";

        String message = new String(msg.getBytes(), "UTF-8");

        PushPayload.Builder PayloadBuilder = PushPayload.newBuilder();
        PayloadBuilder.setPlatform(Platform.all());

        Audience audience = Audience.alias("payment.notify.1025");
        PayloadBuilder.setAudience(audience);

        ClientConfig clientConfig = ClientConfig.getInstance();
        JPushClient client = new JPushClient("c33d371802d3f1ec10adde28", "ae568a3fb2b070894b54edf9", null, clientConfig);
        PayloadBuilder.setMessage(Message.newBuilder().setContentType("pay").setMsgContent(message).build());
        PushPayload payload = PayloadBuilder.build();

        PushResult pushResult = client.sendPush(payload);
    }

    private static String getCertificate() {
        String certificateValue = "";

        WxCertSign certSign = new WxCertSign();
        String nonceStr = RandomStringUtil.randomAlphanumeric(32);

        certSign.setNonce_str(nonceStr);
        certSign.setMch_id(mchId);
        SortedMap<String, String> stringStringSortedMap = certSign.signParams();
        String apiSign = SignatureUtil.createApiSignHMAC(stringStringSortedMap, mchKey);

        certSign.setSign(apiSign);

        SortedMap<String, String> paramsMap = certSign.getParamsMap();
        WxCertRequest request = new WxCertRequest(paramsMap);
        WxCertResponse execute = request.execute();
        String certificates = execute.getCertificates();

        CertificateData certificateData = JSONObject.parseObject(certificates, CertificateData.class);

        if (certificateData != null && certificateData.getData() != null && certificateData.getData().size() > 0) {
            List<Certificate> data = certificateData.getData();
            Certificate certificate = data.get(0);

            final String associatedData = certificate.getEncrypt_certificate().getAssociated_data(); // encrypt_certificate.associated_data
            final String nonce = certificate.getEncrypt_certificate().getNonce(); // encrypt_certificate.nonce
            final String cipherText = certificate.getEncrypt_certificate().getCiphertext(); // encrypt_certificate.ciphertext

            try {
                certificateValue = aesgcmDecrypt(associatedData, nonce, cipherText);
                LogUtil.showLog(certificateValue);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return certificateValue;
    }

    private static String aesgcmDecrypt(String aad, String iv, String cipherText) throws Exception {
        final Cipher cipher = Cipher.getInstance(ALGORITHM, "SunJCE");
        SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");
        GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        cipher.updateAAD(aad.getBytes());
        return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText)));
    }

}
